<template>
    <div class="jsmind_layout">
        <div class="toolbar">
            <div class="tips">操作提示：<span>右键节点打开工具栏、鼠标滚轮可进行缩放、双击可编辑节点、拖拽可改变节点顺序</span> </div>
            <!-- <el-button @click="screen_shot">导出图片</el-button> -->
        </div>
        <div id="jsmind_container"
             ref="container">
        </div>
        <!-- 右键菜单 -->
        <div class="context-menu"
             v-show="showMenu"
             :style="{
        left: menuStyle.left,
        top: menuStyle.top,
        bottom: menuStyle.bottom,
        right: menuStyle.right
      }"
             ref="context">
            <i class="iconfont icon-jiedianleilianjipingtai"
               @click="addBrotherNode"
               title="添加兄弟节点"
               v-if="allowAddBrotherNode"></i>
            <i class="iconfont icon-tianjiazijiedian"
               @click="addNode"
               title="添加子节点"></i>

            <i class="iconfont icon-bianji"
               @click="editNode"
               title="编辑节点"></i>
            <i class="iconfont icon-changyonggoupiaorenshanchu"
               @click="removeNode"
               v-if="allowRemoveNode"
               title="删除节点"></i>
            <i class="iconfont icon-ziti"
               @click="handleFontSet"
               title="字体设置"></i>
            <div class="iconfont iconfont-box"
                 :style="{backgroundColor:activeColor}"
                 @click="handleNodeBg"
                 title="设置节点背景色"></div>
            <div class="font-setting"
                 v-if="fontShow">
                <el-input-number size="small"
                                 v-model="fontSize"
                                 @change="handleChangeTextSize"
                                 @blur="handleChangeTextSize"
                                 style="width:100px"
                                 :min="12"
                                 :max="100"
                                 title="字体大小"></el-input-number>
                <div :class="['blod',isBold?'isblod':'']"
                     @click="handleChangeTextBold"
                     title="字体加粗">B</div>
                <el-color-picker v-model="textColor"
                                 size="small"
                                 style="margin-left:5px"
                                 title="字体颜色"
                                 @change="changeTextColor"></el-color-picker>
            </div>
            <div class="bg-color"
                 v-if="bgColorShow">
                <div :class="['iconfont',item==='#FFFFFF'?'add-border':'']"
                     v-for="(item,index) in nodeColors"
                     :key="index"
                     :style="{backgroundColor:item}"
                     @click="handleChangeNodeColor(item)">
                    <i class="iconfont icon-0-58"
                       v-if="activeColor===item"></i>
                </div>
            </div>
        </div>
    </div>
</template>
<script>
import 'jsmind/style/jsmind.css'
import jsMind from 'jsmind/js/jsmind.js'
window.jsMind = jsMind
require('jsmind/js/jsmind.draggable.js')
require('jsmind/js/jsmind.screenshot.js')
export default {
    props: {
    },

    data () {
        return {
            isBold: false,
            allowAddBrotherNode: true,
            allowRemoveNode: true,
            bgColorShow: false,
            fontShow: false,
            fontSize: 16,
            textColor: '',
            activeColor: '#3ABB54',
            nodeColors: ['#3ABB54', '#FFAD4D', '#2C67FF', '#FE6056', '#000001', '#FFFFFF', '#E6E6E6', '#E2C6AC', '#C7CEEE', '#DAC9FF'],
            mind: {},
            editor: null,
            jm: null,
            showMenu: false, // 是否显示右键菜单栏
            menuStyle: {
                top: '',
                bottom: '',
                left: '',
                right: ''
            },
            maxNodes: 100
        }
    },
    computed: {
    },
    created () {
    },
    mounted () {
        this.getData()
        this.mouseWheel()
    },
    methods: {
        // 设置字体
        handleFontSet () {
            let selectedNode = this.jm.get_selected_node()
            let fontWeight = selectedNode.data['font-weight']
            this.textColor = selectedNode.data['foreground-color']
            this.bgColorShow = false
            this.fontShow = !this.fontShow
            this.isBold = fontWeight && fontWeight > 500
        },
        // 设置背景
        handleNodeBg () {
            this.bgColorShow = !this.bgColorShow
            this.fontShow = false
        },
        // 导出图片
        screen_shot () {
            this.jm.screenshot.shootDownload()
        },
        // 重置视图
        reset () {
            document.querySelector('.root').scrollIntoView({
                block: 'center',
                behavior: 'smooth'
            })
            // this.jm.view.setZoom(1)
        },
        handleChangeTextSize () {
            let selectedNode = this.jm.get_selected_node()
            if (selectedNode) {
                this.jm.set_node_font_style(selectedNode.id, this.fontSize);
            }
            this.reset()
        },
        handleChangeTextBold () {
            this.isBold = !this.isBold;
            let selectedNode = this.jm.get_selected_node()
            if (selectedNode) {
                this.jm.set_node_font_style(selectedNode.id, this.fontSize, this.isBold ? 900 : 400);
            }
            this.reset()
        },
        changeTextColor () {
            let selectedNode = this.jm.get_selected_node()
            if (selectedNode) {
                this.jm.set_node_color(selectedNode.id, selectedNode.data['background-color'], this.textColor)
            }
        },
        handleChangeNodeColor (color) {
            let selectedNode = this.jm.get_selected_node()
            if (!selectedNode) {
                this.$message({ type: 'warning', message: '请先选择一个节点!' })
                return
            }
            this.activeColor = color
            let nodeid = selectedNode.id
            this.jm.set_node_color(nodeid, color, null);
        },
        randomColor () {
            let i = Math.floor(Math.random() * 10);
            return this.nodeColors[i]
        },
        // 获取选中标签的 ID
        get_selected_nodeid () {
            const selectedNode = this.jm.get_selected_node()
            if (selectedNode) {
                return selectedNode.id
            } else {
                return null
            }
        },
        // 单击重置选中背景颜色
        nodeClick () {
            const selectedId = this.get_selected_nodeid()
            if (!selectedId) return
            const nodeObj = this.jm.get_node(selectedId)
            this.jm.set_node_color(selectedId, nodeObj.data['background-color'] || '#3ABB54', nodeObj.data['foreground-color'])
        },
        // 新增子节点
        addNode () {
            const mindData = this.jm.get_data('node_array')
            let nodes = mindData.data.length
            if (nodes === this.maxNodes) {
                this.$message({ type: 'warning', message: '最多创建100个节点!' })
                return
            }

            let selectedNode = this.jm.get_selected_node()
            if (!selectedNode) {
                this.$message({ type: 'warning', message: '请先选择一个节点!' })
                return
            }

            let nodeid = jsMind.util.uuid.newid()
            let topic = 'new Node'
            let newNode = this.jm.add_node(selectedNode, nodeid, topic)
            if (newNode) {
                this.jm.select_node(nodeid)
                this.jm.begin_edit(nodeid)
                this.setNodeBgColor(nodeid)
            }
            if (selectedNode.isroot) {
                this.allowAddBrotherNode = true;
                this.allowRemoveNode = true;
            }
        },
        setNodeBgColor (nodeid) {
            this.jm.set_node_color(nodeid, this.randomColor(), '#333');

        },
        // 新增兄弟节点
        addBrotherNode () {
            const mindData = this.jm.get_data('node_array')
            let nodes = mindData.data.length
            if (nodes === this.maxNodes) {
                this.$message({ type: 'warning', message: '最多创建100个节点!' })
                return
            }
            let selectedNode = this.jm.get_selected_node()
            if (!selectedNode) {
                this.$message({ type: 'warning', message: '请先选择一个节点!' })
                return
            } else if (selectedNode.isroot) {
                this.$message({ type: 'warning', message: '不能在根节点添加，请重新选择节点!' })
                return
            }
            let nodeid = jsMind.util.uuid.newid()
            let topic = 'new Node'
            let newNode = this.jm.insert_node_after(selectedNode, nodeid, topic)
            if (newNode) {
                this.jm.select_node(nodeid)
                this.jm.begin_edit(nodeid)
                this.setNodeBgColor(nodeid)
            }
        },
        // 编辑节点
        editNode () {
            const selectedNode = this.jm.get_selected_node()
            this.jm.view.edit_node_begin(selectedNode)
            this.showMenu = false
        },
        // 删除节点
        removeNode () {
            let selectedId = this.get_selected_nodeid()
            if (!selectedId) {
                this.$message({
                    type: 'warning',
                    message: '请先选择一个节点!'
                })
                return
            }
            this.jm.remove_node(selectedId)
            this.showMenu = false
        },
        getData () {
            this.mind = {
                meta: {
                    name: '',
                    author: '',
                    version: ''
                },
                /* 数据格式声明 */
                format: 'node_tree',
                /* 数据内容 */
                data: {
                    id: 'root',
                    topic: '主题',
                    'background-color': '#2C67FF',
                    'foreground-color': '#FFF',
                    // width:300,
                    // height:300,
                    children: [
                        {
                            id: 'easy', // [必选] ID, 所有节点的ID不应有重复，否则ID重复的结节将被忽略
                            topic: '节点 节点', // [必选] 节点上显示的内容
                            direction: 'right', // [可选] 节点的方向，此数据仅在第一层节点上有效，目前仅支持 left 和 right 两种，默认为 right
                            expanded: true, // [可选] 该节点是否是展开状态，默认为 true
                            children: [
                                {
                                    id: 'easy1',
                                    topic: '节点 节点',
                                    'background-color': '#FFFFFF',
                                    'foreground-color': '#333',
                                },
                                {
                                    id: 'easy2',
                                    topic: '节点 节点',
                                    'background-color': '#FFFFFF',
                                    'foreground-color': '#333',
                                },
                            ]
                        },
                        {
                            id: 'open',
                            topic: '节点 节点',
                            direction: 'right',
                            expanded: true,
                            children: [
                                {
                                    id: 'open1',
                                    topic: '节点 节点',
                                    'background-color': '#FFFFFF',
                                    'foreground-color': '#333',
                                },
                                {
                                    id: 'open2',
                                    topic: '节点 节点',
                                    'background-color': '#FFFFFF',
                                    'foreground-color': '#333',
                                }
                            ]
                        },
                    ]
                }
            }
            this.open_empty()
        },
        open_empty () {
            const options = {
                container: 'jsmind_container', // 必选，容器ID
                editable: true, // 可选，是否启用编辑
                theme: 'success', // 可选，主题
                view: {
                    line_width: 2, // 思维导图线条的粗细
                    line_color: 'skyblue', // 思维导图线条的颜色
                    draggable: true,   // 当容器不能完全容纳思维导图时，是否允许拖动画布代替鼠标滚动
                    hide_scrollbars_when_draggable: true // 当设置 draggable = true 时，是否隐藏滚动条
                },
                shortcut: {
                    enable: false // 禁用快捷键
                },
                mode: 'side', // 显示模式，子节点只分布在根节点右侧
                menuOpts: {  // 这里加入一个专门配置menu的对象
                    showMenu: false, //showMenu 为 true 则打开右键功能 ，反之关闭
                    injectionList: [],
                }
            }
            this.jm = jsMind.show(options, this.mind)
            this.editor = this.jm.view.e_editor
            this.addEvent()

        },

        addEvent () {
            let events = ['click', 'contextmenu', 'dblclick']
            events.forEach(eventName => {
                this.jm.view.add_event(this.editor, eventName, (e) => {
                    e.preventDefault()
                    const selectedNode = this.jm.get_selected_node()

                    if (!selectedNode) {
                        this.showMenu = false
                        return
                    }
                    if (['click', 'dblclick'].includes(eventName)) {
                        this.showMenu = false
                    }
                    this.activeColor = selectedNode.data['background-color'] || '#3ABB54';
                    this.nodeClick()
                    if (eventName === 'contextmenu') {
                        let selectedNode = this.jm.get_selected_node()
                        this.allowAddBrotherNode = !selectedNode.isroot;
                        this.allowRemoveNode = !selectedNode.isroot;
                        this.fontShow = false;
                        this.bgColorShow = false;

                        const el = document.querySelector('.context-menu')
                        const width = parseFloat(window.getComputedStyle(el).width)
                        const height = parseFloat(window.getComputedStyle(el).height) * 3 + 12
                        const windowHeight = window.innerHeight
                        const windowWidth = window.innerWidth

                        // 极限位置 避免越界
                        if (e.clientY + height > windowHeight) {
                            this.menuStyle.left = e.clientX + 'px'
                            this.menuStyle.top = 'unset'
                            this.menuStyle.bottom = 0
                        } else if (e.clientX + width > windowWidth) {
                            this.menuStyle.top = e.clientY + 'px'
                            this.menuStyle.left = 'unset'
                            this.menuStyle.right = 0
                        } else {
                            this.menuStyle.left = e.clientX + 'px'
                            this.menuStyle.top = e.clientY + 'px'
                            this.menuStyle.bottom = 'unset'
                        }
                        this.showMenu = true
                    }
                })
            })
        },
        // 放大
        zoomIn () {
            this.jm.view.zoomIn()
        },
        // 缩小
        zoomOut () {
            this.jm.view.zoomOut()
        },
        scrollFunc (e) {
            e.preventDefault()
            e = e || window.event
            if (e.wheelDelta) {
                if (e.wheelDelta > 0) {
                    this.zoomIn()
                } else {
                    this.zoomOut()
                }
            } else if (e.detail) {
                if (e.detail > 0) {
                    this.zoomIn()
                } else {
                    this.zoomOut()
                }
            }
            this.reset()
            // this.jm.resize()
        },
        // 鼠标滚轮放大缩小
        mouseWheel () {
            if (document.addEventListener) {
                document.addEventListener('domMouseScroll', this.scrollFunc, false)
            }
            this.$refs.container.onmousewheel = this.scrollFunc
        }
    },
    beforeDestroy () {
        document.removeEventListener('domMouseScroll', this.scrollFunc, false)
    }
}
</script>
<style lang="less" scoped>
.jsmind_layout {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    height: calc(100% - 40px);
    overflow: hidden;
    /deep/ .el-button--medium,
    /deep/ .el-input--medium {
        margin-top: 10px;
    }
}
/deep/ jmnode.selected {
    background-color: #b9b9b9;
    box-shadow: 2px 2px 8px #777 !important;
}
jmnode:hover {
    box-shadow: 2px 2px 8px #777 !important;
}
#jsmind_container {
    flex: 1 1 auto;
    position: relative;
}
.jsmind-inner {
    overflow: hidden auto !important;
}
/* 隐藏滚动条 */
.jsmind-inner::-webkit-scrollbar {
    display: none;
}
</style>
<style lang="less" scoped>
@import "./demo.less";
</style>